/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package ru.icq.io;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.apache.log4j.Logger;
import ru.icq.accounts.AccountInfo;
import ru.icq.accounts.GeneralAccountjICQ;
import ru.icq.io.connections.ProtocolType;
import ru.icq.exceptions.PropertiesExceptions;
import ru.icq.exceptions.errors.PropertiesError;

/**
 * Загрузка/Сохранение настроек приложения.
 * @author Носов А.В.
 */
public class FileProperties {

    // Variables declaration
    private static final Logger log = Logger.getLogger(FileProperties.class);
    private static String res = System.getProperty("user.dir") + File.separator + "jICQ.properties";
    private static Properties properties;
    // End of variables declaration

    public static Properties loadProperties() throws PropertiesExceptions {
        properties = new Properties();
        try {
            properties.load(new FileInputStream(res));
        } catch (IOException ex) {
            File f = new File(res);
            try {
                f.createNewFile();
                createjICQProperties(f);
            } catch (IOException e) {
                log.error("Нет доступа к диску", e);
                throw new PropertiesExceptions(PropertiesError.EMPTY_NO_DISK);
            }
            log.error("Ошибка загрузки файла настроек.");
        }
        return properties;
    }

    /**
     * Сохранение настроект приложения.
     * @param p настройки
     */
    public static void saveProperties(Properties p) {
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(res);
            p.store(out, "/* properties updated */");
        } catch (IOException ex) {
            log.error("Ошибка записи файла настроек.");
        } finally {
            try {
                out.close();
            } catch (IOException ex) {
                log.error("Ошибка при закрытии файла настроек.");
            }
        }
    }

    /**
     * Создание настроек jICQ по умолчанию.
     * @param f файл
     * @throws IOException 
     */
    private static void createjICQProperties(File f) throws IOException {
        FileOutputStream out = new FileOutputStream(f);
        properties.put("jICQ.window.height", "600");
        properties.put("jICQ.window.width", "250");
        properties.put("jICQ.extendedState", "0");
//        properties.put("jICQ.theme", "Default");
//        properties.put("jICQ.language", "Russian");
        properties.put("jICQ.window.x", "50");
        properties.put("jICQ.window.y", "50");
        properties.put("jICQ.last_user", "");
        properties.store(out, "/* create jICQ properties */");
    }

    /**
     * Возвращает список созданных пользователей.
     * @return список пользователей
     */
    public static Map getUsers() {
        Map users = new HashMap();
        String dir = System.getProperty("user.dir") + File.separator + "Users";
        File[] files = new File(dir).listFiles();
        for (File file : files) {
            if (file.isDirectory()) {
                if (file.getName().startsWith("jICQ.")) {
                    if (new File(file.getAbsolutePath() + 
                            File.separator + "settings.properties").exists()) {
                        String name = file.getName();
                        users.put(name.substring(5, name.length()), file);
                    }
                }
            }
        }
        return users;
    }

    /**
     * Возвращает список аккаунтов пользователя.
     * @param f путь к папке пользователя
     */
    public static Map<String, GeneralAccountjICQ> getAccounts(File f) {
//        log.info("----- getAccounts: " + f.getName());
        Map<String, GeneralAccountjICQ> accounts = new HashMap<String, GeneralAccountjICQ>();
        File[] files = new File(f.getAbsolutePath()).listFiles();
        for (File file : files) {
            if (file.isDirectory()) {
                if (file.getName().startsWith(ProtocolType.ICQ.toString())) {
                    if (new File(file.getAbsolutePath() + 
                            File.separator + "account.properties").exists()) {
//                        log.info(file.getName());
                        GeneralAccountjICQ ga = loadAccount(file.getAbsolutePath() + 
                                File.separator + "account.properties", ProtocolType.ICQ);
                        accounts.put(ga.getUid(), ga);
                    }
                } else if (file.getName().startsWith(ProtocolType.JABBER.toString())) {
                    if (new File(file.getAbsolutePath() + 
                            File.separator + "account.properties").exists()) {
//                        log.info(file.getName());
                        GeneralAccountjICQ ga = loadAccount(file.getAbsolutePath() + 
                                File.separator + "account.properties", ProtocolType.JABBER);
                        accounts.put(ga.getUid(), ga);
                    }
                } else if (file.getName().startsWith(ProtocolType.VKONTAKTE.toString())) {
                    if (new File(file.getAbsolutePath() + 
                            File.separator + "account.properties").exists()) {
//                        log.info(file.getName());
                        GeneralAccountjICQ ga = loadAccount(file.getAbsolutePath() + 
                                File.separator + "account.properties", ProtocolType.VKONTAKTE);
                        accounts.put(ga.getUid(), ga);
                    }
                }
            }
        }
//        log.info("-----");
        return accounts;
    }

    /**
     * Загрузка настроек аккаунта.
     * @param path путь к настройкам
     * @return аккаунт
     */
    private static GeneralAccountjICQ loadAccount(String path, ProtocolType type) {
        try {
            Properties p = loadProperties(path);
            AccountInfo account = new AccountInfo(type);
            account.setPassword(p.getProperty("pass"));
            account.setServer(p.getProperty("server"));
            account.setPort(Integer.valueOf(p.getProperty("port")));
            account.setAutoinput(Boolean.parseBoolean(p.getProperty("input")));
            return new GeneralAccountjICQ(account);
        } catch (NullPointerException ex) {
            log.error("Ошибка загрузки аккаунта - " + path);
            return null;
        }
    }

    /**
     * Создание файла настроек.
     * @param path путь к файлу
     * @param p настройки
     * @throws PropertiesExceptions ошибка при создании файла
     */
    public static void createProperties(String path, Properties p) throws PropertiesExceptions {
        File file = new File(path);
        try {
            file.createNewFile();
            FileOutputStream out = new FileOutputStream(file);
            p.store(out, "/* create properties */");
            out.close();
        } catch (IOException e) {
            log.error("Нет доступа к диску", e);
            throw new PropertiesExceptions(PropertiesError.EMPTY_NO_DISK);
        }
    }

    /**
     * Возвращает загруженный файл настроек.
     * @param path путь к файлу
     * @return настройки
     */
    public static Properties loadProperties(String path) {
        Properties p = new Properties();
        try {
            p.load(new FileInputStream(path));
        } catch (IOException ex) {
            return null;
        }
        return p;
    }
}
